@echo off
setlocal enabledelayedexpansion

set DEBUGMODE=default
set DOCKER_IMAGE_VERSION_DEFAULT=1.0.0
set DOCKER_IMAGE_BASENAME_DEFAULT=bizark_epic
set DOMAIN_DEFAULT=thebizark.com
set DOCKER_REGISTRY_USERNAME_DEFAULT=bizark
set DOCKER_REGISTRY_HOST_DEFAULT=docker.bizarkdev.com
set DOCKER_REGISTRY_REPOSITORY_DEFAULT=thebizark
if "%DOCKER_IMAGE_VERSION%"=="" (
    set DOCKER_IMAGE_VERSION=%DOCKER_IMAGE_VERSION_DEFAULT%
)
if "%DOCKER_IMAGE_BASENAME%"=="" (
    set DOCKER_IMAGE_BASENAME=%DOCKER_IMAGE_BASENAME_DEFAULT%
)
if "%DOMAIN%"=="" (
    set DOMAIN=%DOMAIN_DEFAULT%
)
if "%DOCKER_REGISTRY_USERNAME%"=="" (
    set DOCKER_REGISTRY_USERNAME=%DOCKER_REGISTRY_USERNAME_DEFAULT%
)
if "%DOCKER_REGISTRY_HOST%"=="" (
    set DOCKER_REGISTRY_HOST=%DOCKER_REGISTRY_HOST_DEFAULT%
)
if "%DOCKER_REGISTRY_REPOSITORY%"=="" (
    set DOCKER_REGISTRY_REPOSITORY=%DOCKER_REGISTRY_REPOSITORY_DEFAULT%
)

set PRJ_PATH=%~dp0
set PRJ_PATH=%PRJ_PATH:~0,-1%
set PRJ_M2_PATH=%PRJ_PATH%\.mvn\settings
set PRJ_CERTS_PATH=%PRJ_PATH%\.certs
set DOCKER_BUILDKIT=1
set BUILDKIT_STEP_LOG_MAX_SIZE=-1
set BUILDKIT_STEP_LOG_MAX_SPEED=-1
set DATA_PATH=%PRJ_PATH%\data
set DATA_TPL_PATH=%PRJ_PATH%\extra\data_template
set HOME_PATH=""
if "%USERPROFILE%"=="" (
  if "%HOME%"=="" (
    rem set HOME_PATH=C:\Users\Administrator
    echo "Detect home directory failed"
    exit /b
  ) else (
    set HOME_PATH=%HOME%
  )
) else (
  set HOME_PATH=%USERPROFILE%
)
set DOT_DOCKER_PATH=%HOME_PATH%\.docker
set DOT_DOCKER_DATA_PATH=%DOT_DOCKER_PATH%\data
set DATA_PATH_HOST=%DOT_DOCKER_DATA_PATH%
set CODE_PATH=%HOME_PATH%\Code
set CODE_DATA_PATH=%CODE_PATH%\data

set DOCKERPW_CONF_FILEPATH=%PRJ_PATH%\dockerpw.conf
if exist %DOCKERPW_CONF_FILEPATH% (
    FOR /F "tokens=*" %%i in ('type dockerpw.conf') do SET %%i
)

set ACTION=""
if "%1"=="" (
    set ACTION=help
) else (
    set ACTION=%1
)
shift

set APP_MOD=all
if "%ACTION%"=="run" goto setupAppMod
if "%ACTION%"=="up" goto setupAppMod
if "%ACTION%"=="daemon" goto setupAppMod
if "%ACTION%"=="logs" goto setupAppMod
if "%ACTION%"=="sh" goto setupAppMod
if "%ACTION%"=="stop" goto setupAppMod
if "%ACTION%"=="download" goto setupAppMod

:setupVars

set APP_ENV=""
if "%1"=="" (
    set APP_ENV=dev
) else (
    set APP_ENV=%1
)
if %APP_ENV%==prod (
    set APP_VER=latest
) else (
    set APP_VER=%APP_ENV%
)
shift
if "%1"=="" (
    set DEBUGMODE=default
) else (
    set DEBUGMODE=%1
)
shift

goto processFlow

:setupAppMod

if "%1"=="" (
    set APP_MOD=all
) else (
    set APP_MOD=%1
)
shift
goto setupVars

:processFlow
echo .
echo DOCKER_IMAGE_BASENAME: %DOCKER_IMAGE_BASENAME%
echo DOCKER_IMAGE_VERSION: %DOCKER_IMAGE_VERSION%
echo action: %ACTION%
echo app mod: %APP_MOD%
echo app env: %APP_ENV%
echo app version: %APP_VER%
echo debug mode: %DEBUGMODE%
echo .

rem exit /b

if "%ACTION%"=="login" (
    docker login --username=%DOCKER_REGISTRY_USERNAME% %DOCKER_REGISTRY_HOST%
    goto END
) else if "%ACTION%"=="prepare" (
    if not exist %DOT_DOCKER_PATH% (
        md %DOT_DOCKER_PATH%
    )
    if not exist %DOT_DOCKER_DATA_PATH% (
        md %DOT_DOCKER_DATA_PATH%
    )
    if not exist %DATA_PATH% (
        mklink /d %DATA_PATH% %DATA_PATH_HOST%
    )
    if exist %CODE_PATH% (
        if not exist %CODE_DATA_PATH% (
            mklink /d %CODE_DATA_PATH% %DATA_PATH_HOST%
        )
    )

@REM     if not exist %PRJ_M2_PATH% (
@REM         md %PRJ_M2_PATH%
@REM     )
@REM     if not exist %PRJ_M2_PATH%\settings.xml (
@REM         if exist %HOME_PATH%\.m2\settings.xml (
@REM             xcopy /d /y %HOME_PATH%\.m2\settings.xml %PRJ_M2_PATH%\
@REM         )
@REM     )

    if not exist %PRJ_CERTS_PATH% (
        md %PRJ_CERTS_PATH%
    )
    if not exist %PRJ_CERTS_PATH%\%DOMAIN% (
        md %PRJ_CERTS_PATH%\%DOMAIN%
    )
    if exist %DATA_PATH%\etc\ssl\certs\%DOMAIN% (
        xcopy /d /e /s /y %DATA_PATH%\etc\ssl\certs\%DOMAIN% %PRJ_CERTS_PATH%\%DOMAIN%
    )

    if exist %DATA_TPL_PATH% (
        xcopy /d /e /s /y %DATA_TPL_PATH% %DATA_PATH%
    )
    goto END
) else if "%ACTION%"=="setupbuildx" (
    docker buildx rm mybuild
    docker buildx create --driver-opt env.BUILDKIT_STEP_LOG_MAX_SIZE=1000000,env.BUILDKIT_STEP_LOG_MAX_SPEED=100000000 --use --node mybuild --name mybuild
    docker buildx use mybuild
    goto END
) else if "%ACTION%"=="package" (
    cd %PRJ_PATH%
    npm i
    if "%APP_ENV%"=="prod" (
        npm run build
    ) else (
        npm run build:%APP_ENV%
    )
    goto END
) else if "%ACTION%"=="build" (
    cd %PRJ_PATH%
    if "%DEBUGMODE%"=="debug" (
        docker build -m 3g --memory-swap=-1 -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DEBUGMODE% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
    ) else (
        if "%APP_ENV%"=="prod" (
            docker build -m 3g --memory-swap=-1 -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER% -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DOCKER_IMAGE_VERSION% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
        ) else (
            docker build -m 3g --memory-swap=-1 -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
        )
    )
    goto END
) else if "%ACTION%"=="buildnocache" (
    cd %PRJ_PATH%
    if "%DEBUGMODE%"=="debug" (
        docker build -m 3g --memory-swap=-1 --no-cache -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DEBUGMODE% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
    ) else (
        if "%APP_ENV%"=="prod" (
            docker build -m 3g --memory-swap=-1 --no-cache -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER% -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DOCKER_IMAGE_VERSION% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
        ) else (
            docker build -m 3g --memory-swap=-1 --no-cache -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
        )
    )
    goto END
) else if "%ACTION%"=="buildx" (
    cd %PRJ_PATH%
    if "%DEBUGMODE%"=="debug" (
        docker buildx build -m 3g --memory-swap=-1 -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DEBUGMODE% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
    ) else (
        if "%APP_ENV%"=="prod" (
            docker buildx build -m 3g --memory-swap=-1 -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER% -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DOCKER_IMAGE_VERSION% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
        ) else (
            docker buildx build -m 3g --memory-swap=-1 -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
        )
    )
    goto END
) else if "%ACTION%"=="buildxnocache" (
    cd %PRJ_PATH%
    if "%DEBUGMODE%"=="debug" (
        docker buildx build -m 3g --memory-swap=-1 --no-cache -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DEBUGMODE% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
    ) else (
        if "%APP_ENV%"=="prod" (
            docker buildx build -m 3g --memory-swap=-1 --no-cache -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER% -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DOCKER_IMAGE_VERSION% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
        ) else (
            docker buildx build -m 3g --memory-swap=-1 --no-cache -f %DEBUGMODE%.Dockerfile -t %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER% --build-arg SPRING_PROFILES_ACTIVE=%APP_ENV% .
        )
    )
    goto END
) else if "%ACTION%"=="up" (
    cd %PRJ_PATH%
    if "%APP_MOD%"=="all" (
        if "%DEBUGMODE%"=="debug" (
            docker-compose -p %DOCKER_IMAGE_BASENAME% -f docker-compose.debug.yml up --no-build
        ) else (
            docker-compose -p %DOCKER_IMAGE_BASENAME% up --no-build
        )
    ) else (
        if "%DEBUGMODE%"=="debug" (
            docker-compose -p %DOCKER_IMAGE_BASENAME% -f docker-compose.debug.yml up --no-build %DOCKER_IMAGE_BASENAME%_%APP_MOD%
        ) else (
            docker-compose -p %DOCKER_IMAGE_BASENAME% up --no-build %DOCKER_IMAGE_BASENAME%_%APP_MOD%
        )
    )
    goto END
) else if "%ACTION%"=="run" (
    if "%APP_MOD%"=="all" (
        docker-compose -p %DOCKER_IMAGE_BASENAME% run %DOCKER_IMAGE_BASENAME%
    ) else (
        docker-compose -p %DOCKER_IMAGE_BASENAME% run %DOCKER_IMAGE_BASENAME%_%APP_MOD%
    )
    goto END
) else if "%ACTION%"=="daemon" (
    cd %PRJ_PATH%
    if "%APP_MOD%"=="all" (
        if "%DEBUGMODE%"=="debug" (
            docker-compose -p %DOCKER_IMAGE_BASENAME% -f docker-compose.debug.yml up --no-build -d
        ) else (
            docker-compose -p %DOCKER_IMAGE_BASENAME% up --no-build -d
        )
    ) else (
        if "%DEBUGMODE%"=="debug" (
            docker-compose -p %DOCKER_IMAGE_BASENAME% -f docker-compose.debug.yml up --no-build -d %DOCKER_IMAGE_BASENAME%_%APP_MOD%
        ) else (
            docker-compose -p %DOCKER_IMAGE_BASENAME% up --no-build -d %DOCKER_IMAGE_BASENAME%_%APP_MOD%
        )
    )
    goto END
) else if "%ACTION%"=="logs" (
    if "%APP_MOD%"=="all" (
        docker-compose -p %DOCKER_IMAGE_BASENAME% logs -tf --tail=1000
    ) else (
        docker-compose -p %DOCKER_IMAGE_BASENAME% logs -tf --tail=1000 %DOCKER_IMAGE_BASENAME%_%APP_MOD%
    )
    goto END
) else if "%ACTION%"=="sh" (
    if "%DEBUGMODE%"=="debug" (
        if "%APP_MOD%"=="all" (
            docker-compose -p %DOCKER_IMAGE_BASENAME% -f docker-compose.debug.yml exec -u www %DOCKER_IMAGE_BASENAME% /bin/bash
        ) else (
            docker-compose -p %DOCKER_IMAGE_BASENAME% -f docker-compose.debug.yml exec -u www %DOCKER_IMAGE_BASENAME%_%APP_MOD% /bin/bash
        )
    ) else (
        if "%APP_MOD%"=="all" (
            docker-compose -p %DOCKER_IMAGE_BASENAME% exec -u nginx %DOCKER_IMAGE_BASENAME% /bin/bash
        ) else (
            docker-compose -p %DOCKER_IMAGE_BASENAME% exec -u nginx %DOCKER_IMAGE_BASENAME%_%APP_MOD% /bin/bash
        )
    )
    goto END
) else if "%ACTION%"=="stop" (
    if "%DEBUGMODE%"=="debug" (
        if "%APP_MOD%"=="all" (
            docker-compose -p %DOCKER_IMAGE_BASENAME% -f docker-compose.debug.yml stop -t 60
        ) else (
            docker-compose -p %DOCKER_IMAGE_BASENAME% -f docker-compose.debug.yml stop -t 60 %DOCKER_IMAGE_BASENAME%_%APP_MOD%
        )
    ) else (
        if "%APP_MOD%"=="all" (
            docker-compose -p %DOCKER_IMAGE_BASENAME% stop -t 60
        ) else (
            docker-compose -p %DOCKER_IMAGE_BASENAME% stop -t 60 %DOCKER_IMAGE_BASENAME%_%APP_MOD%
        )
    )
    goto END
) else if "%ACTION%"=="down" (
    if "%DEBUGMODE%"=="debug" (
        docker-compose -p %DOCKER_IMAGE_BASENAME% -f docker-compose.debug.yml down
    ) else (
        docker-compose -p %DOCKER_IMAGE_BASENAME% down
    )
    goto END
) else if "%ACTION%"=="push" (
    if "%DEBUGMODE%"=="debug" (
        docker push %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DEBUGMODE%
    ) else (
        if "%APP_ENV%"=="prod" (
            docker push %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER%
            docker push %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DOCKER_IMAGE_VERSION%
        ) else (
            docker push %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER%
        )
    )
    goto END
) else if "%ACTION%"=="pull" (
    if "%DEBUGMODE%"=="debug" (
        docker pull %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DEBUGMODE%
    ) else (
        docker pull %DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER%
    )
    goto END
) else if "%ACTION%"=="download" (
    set pwimageId=%DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%APP_VER%
    if "%DEBUGMODE%"=="debug" (
        set pwimageId=%DOCKER_REGISTRY_HOST%/%DOCKER_REGISTRY_REPOSITORY%/%DOCKER_IMAGE_BASENAME%:%DEBUGMODE%
    )
    for /f %%G in ('docker create !pwimageId!') do set pwcontainerId=%%G
    echo !pwcontainerId!
    docker cp !pwcontainerId!:/home/www/Code/%DOCKER_IMAGE_BASENAME%/current/dist .
    docker rm -v !pwcontainerId!
    echo done
    goto END
) else (
    echo USAGE ARGS: [action] [env] [debugmode]
    echo actions: prepare package build up run logs sh stop login push pull daemon download
    echo envs:
    echo dev
    echo test
    echo stage
    echo prod
    echo debugmode:
    echo debug
    echo default
    echo .
    echo example usages:
    echo build dev debug
    echo build test
    echo up all prod default
    echo login
    echo .
    echo workflows:
    echo [Local Build]
    echo login (run once)
    echo prepare  (run once)
    echo package (optional)
    echo build
    echo up (check status,errors)
    echo logs (check status,errors)
    echo sh (check status,errors)
    echo stop
    echo push (push to server)
    echo .
    echo [Remote Run]
    echo login (run once)
    echo pull
    echo daemon
    echo .
)

:END
